# -*- coding: utf-8 -*-
import datetime
import json
import logging
import traceback
import uuid
from collections import OrderedDict

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from TemplateChaceAdmin.basic import CCAIResponse
from TemplateChaceAdmin.code import SERVER_ERROR, PARAMS_ERR
from utils.custom import RbacPermission, CustomViewBase, req_operate_by_user
from ..models import DataDictionary, DataDictionaryDetail
from ..serializers.dict_serializer import DictSerializer, DictDetailSerializer

logger = logging.getLogger('error')


class DataDictionaryViewSet(CustomViewBase):
    '''
    字典管理：增删改查
    '''
    perms_map = ({'*': 'admin'}, {'*': 'dictionary_all'}, {'get': 'dictionary_list'}, {'post': 'dictionary_create'},
                 {'put': 'dictionary_edit'},
                 {'delete': 'dictionary_delete'})
    queryset = DataDictionary.objects.all()
    serializer_class = DictSerializer
    filter_backends = (SearchFilter, OrderingFilter)
    search_fields = ('DictionaryCode', 'DictionaryValue')
    ordering_fields = ('id',)
    authentication_classes = (JSONWebTokenAuthentication,)
    permission_classes = (RbacPermission,)

    def list(self, request, *args, **kwargs):
        '''
        重写list方法
        '''
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        tree_dict = {}
        tree_data = []
        try:
            for item in serializer.data:
                tree_dict[item['dict_id']] = item
            for i in tree_dict:
                if tree_dict[i]['parent_id'] and tree_dict[i]['parent_id'] != "0":  # 顶级的父级是 0，所以跳过
                    pid = tree_dict[i]['parent_id']
                    parent = tree_dict[pid]
                    parent.setdefault('children', []).append(tree_dict[i])
                else:
                    tree_data.append(tree_dict[i])
            results = tree_data
        except Exception as e:
            logger.error("get dict list failed: \n%s" % traceback.format_exc())
            return CCAIResponse("获取字典列表失败", SERVER_ERROR)

        return CCAIResponse(results)

    def create(self, request, *args, **kwargs):
        '''添加数据POST'''
        try:
            data = req_operate_by_user(request)
            data['dict_id'] = uuid.uuid4().__str__()

            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            # headers = self.get_success_headers(serializer.data)
            return CCAIResponse(data="success")
        except Exception as e:
            logger.error("dict  create failed: \n%s" % traceback.format_exc())
            return CCAIResponse("create failed", SERVER_ERROR)


class DataDictionaryDetailTreeViewSet(CustomViewBase):
    '''
    字典详情树
    '''
    perms_map = ({'*': 'admin'}, {'*': 'dictionarydetail_all'}, {'get': 'dictionarydetail_list'},
                 {'post': 'dictionarydetail_create'}, {'put': 'dictionarydetail_edit'},
                 {'delete': 'dictionarydetail_delete'})
    queryset = DataDictionaryDetail.objects.all()
    serializer_class = DictDetailSerializer
    filter_backends = (SearchFilter, OrderingFilter)
    ordering_fields = ('id',)
    authentication_classes = (JSONWebTokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def list(self, request, *args, **kwargs):
        '''
        重写list方法
        '''
        parent_code = request.GET.get("parent_code")
        is_enabled = request.GET.get("is_enabled")
        label = request.GET.get("label")
        order = request.GET.get("order")
        sort = request.GET.get("ordering")
        order_by = 'id'
        if order and sort:
            if order == '1':
                order_by = sort
            else:
                order_by = '-' + sort

        tree_dict = {}
        tree_data = []
        dict_map = {}
        results = {}

        if parent_code:
            try:
                condtions = OrderedDict()
                if is_enabled:
                    condtions['IsEnabled'] = is_enabled
                if label:
                    condtions['FullName__contains'] = label
                condtions['ParentCode__istartswith'] = parent_code
                # condtions['ParentCode'] = parent_code

                queryset = DataDictionaryDetail.objects.filter(**condtions).order_by(order_by)
                serializer = self.get_serializer(queryset, many=True)
                for item in serializer.data:
                    dict_map[item['dict_code']] = item['label']

                for item in serializer.data:
                    tree_dict[item['dict_detail_id']] = item
                for i in tree_dict:
                    data = tree_dict[i]
                    parent_id = tree_dict[i]['parent_id']
                    parent_code = tree_dict[i]['parent_code']
                    if parent_id and parent_code in dict_map and parent_code != 'CusMYType_XSSRZZL':
                        pid = parent_id
                        parent = tree_dict[pid]
                        parent.setdefault('children', []).append(data)
                    else:
                        tree_data.append(data)
                results['list'] = tree_data

                results['map'] = dict_map
                return CCAIResponse(results)
            except Exception as e:
                logger.error("get dict detail tree failed: \n%s" % traceback.format_exc())
                return CCAIResponse("获取字典详情树失败", SERVER_ERROR)
        else:
            return CCAIResponse(PARAMS_ERR, SERVER_ERROR)

    def create(self, request, *args, **kwargs):
        '''添加数据POST'''
        try:
            data = req_operate_by_user(request)
            data['dict_detail_id'] = uuid.uuid4().__str__()

            serializer = self.get_serializer(data=data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            # headers = self.get_success_headers(serializer.data)
            return CCAIResponse(data="success")
        except Exception as e:
            logger.error("dict detail  create failed: \n%s" % traceback.format_exc())
            return CCAIResponse("create failed", SERVER_ERROR)

    # 获取地区字典接口 - 从redis从获取
    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
            url_path="getDictList", url_name="getDictList")
    def getDictList(self, request):
        parent_code = request.GET.get("parent_code")
        if parent_code:
            if parent_code == '':
                return CCAIResponse("parent_code参数不能为空!", status=status.HTTP_400_BAD_REQUEST)
            from django_redis import get_redis_connection
            startTime = datetime.datetime.now()
            # print(datetime.datetime.now())
            conn = get_redis_connection('default')
            # conn.hset('dicList', 'area', 1)
            # print(conn.hget('dicList', parent_code))
            str = conn.hget('dicList', parent_code)
            endTime = datetime.datetime.now()
            # print(datetime.datetime.now())
            # print((endTime - startTime).seconds)
            return CCAIResponse(data=str)
        else:
            return CCAIResponse("parent_code参数不能为空!", status=status.HTTP_400_BAD_REQUEST)

    # 设置地区字典接口 - 存储到redis中
    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated],
            url_path="setDictList", url_name="setDictList")
    def setDictList(self, request):

        parent_code = request.GET.get("parent_code")
        is_enabled = request.GET.get("is_enabled")
        label = request.GET.get("label")
        order = request.GET.get("order")
        sort = request.GET.get("ordering")
        order_by = 'id'
        if order and sort:
            if order == '1':
                order_by = sort
            else:
                order_by = '-' + sort

        tree_dict = {}
        tree_data = []
        dict_map = {}
        results = {}

        if parent_code:
            try:
                condtions = OrderedDict()
                if is_enabled:
                    condtions['IsEnabled'] = is_enabled
                if label:
                    condtions['FullName__contains'] = label
                condtions['ParentCode__istartswith'] = parent_code
                # condtions['ParentCode'] = parent_code

                queryset = DataDictionaryDetail.objects.filter(**condtions).order_by(order_by)
                serializer = self.get_serializer(queryset, many=True)
                for item in serializer.data:
                    dict_map[item['dict_code']] = item['label']
                for item in serializer.data:
                    tree_dict[item['dict_detail_id']] = item
                for i in tree_dict:
                    if tree_dict[i]['parent_id'] and tree_dict[i]['parent_code'] in dict_map:
                        pid = tree_dict[i]['parent_id']
                        parent = tree_dict[pid]
                        parent.setdefault('children', []).append(tree_dict[i])
                    else:
                        tree_data.append(tree_dict[i])
                results['list'] = tree_data

                results['map'] = dict_map
                from django_redis import get_redis_connection
                conn = get_redis_connection('default')
                str = json.dumps(results).encode('utf-8').decode('unicode_escape')
                # print(str)
                conn.hset('dicList', parent_code, str)
                return CCAIResponse(data="success")
            except Exception as e:
                logger.error("get dict detail tree failed: \n%s" % traceback.format_exc())
                return CCAIResponse("获取字典详情树失败", SERVER_ERROR)


class DataDictionaryDetailListViewSet(ModelViewSet):
    '''
    字典详情列表
    '''
    perms_map = ({'*': 'admin'}, {'*': 'dictionarydetail_list_all'}, {'get': 'dictionarydetail_list_list'},
                 {'post': 'dictionarydetail_list_create'}, {'put': 'dictionarydetail_listlist_edit'},
                 {'delete': 'dictionarydetail_list_delete'})
    queryset = DataDictionaryDetail.objects.all()
    serializer_class = DictDetailSerializer
    filter_backends = (SearchFilter, OrderingFilter)
    ordering_fields = ('id',)
    authentication_classes = (JSONWebTokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def list(self, request, *args, **kwargs):
        '''
        重写list方法
        '''
        parent_code = request.GET.get("parent_code")
        is_enabled = request.GET.get("is_enabled")
        label = request.GET.get("label")
        order = request.GET.get("order")
        sort = request.GET.get("ordering")
        select_all = request.GET.get("select_all")

        dict_list = []
        dict_map = {}
        dict_value_map = {}
        results = {}

        order_by = '-id'
        if order and sort:
            if order == '1':
                order_by = sort
            else:
                order_by = '-' + sort

        if parent_code:
            try:
                condtions = OrderedDict()
                if label:
                    condtions['FullName__contains'] = label
                if is_enabled:
                    condtions['IsEnabled'] = is_enabled
                if select_all:
                    condtions['ParentCode__istartswith'] = parent_code
                else:
                    condtions['ParentCode'] = parent_code

                queryset = DataDictionaryDetail.objects.filter(**condtions).order_by(order_by)
                serializer = self.get_serializer(queryset, many=True)

                for item in serializer.data:
                    item['children'] = []
                    item['hasChildren'] = True
                    dict_list.append(item)
                    dict_map[item['dict_code']] = item['label']
                    dict_value_map[item['dict_val']] = item['label']

                results['list'] = dict_list

                results['map'] = dict_map
                results['value_map'] = dict_value_map
                return CCAIResponse(results)
            except Exception as e:
                logger.error("get dict detail tree failed: \n%s" % traceback.format_exc())
                return CCAIResponse("获取字典详情列表失败", SERVER_ERROR)
        else:
            return CCAIResponse(PARAMS_ERR, SERVER_ERROR)
